package ttsolver.input;

import java.util.Comparator;
import java.util.Hashtable;

import ttsolver.enums.Direction;
import ttsolver.enums.TrainType;
import ttsolver.util.InstantesUtil;

public class Train {
	private String header;
	private int entryTime;
	private Long originNodeId;
	private Long destinationNodeId;
	private Direction direction;
	private double speedMutiplier;
	private double trainLength;
	private int toneladas;
	private boolean isHazmat;
	private int saStatus;
	private Hashtable<Long, Double> scheduleList;
	private int twt;
	private Long id;
	private TrainType type;

	public Train() {
		setScheduleList(new Hashtable<Long, Double>());
	}

	public String getHeader() {
		return header;
	}

	public void setHeader(String header) {
		this.header = header;
		setType(header);
	}

	public TrainType getType() {
		return type;
	}

	public void setType(TrainType type) {
		this.type = type;
	}

	public void setType(String header) {
		switch (header.charAt(0)) {
		case 'A':
			this.type = TrainType.A;
			break;
		case 'B':
			this.type = TrainType.B;
			break;
		case 'C':
			this.type = TrainType.C;
			break;
		case 'D':
			this.type = TrainType.D;
			break;
		case 'E':
			this.type = TrainType.E;
			break;
		case 'F':
			this.type = TrainType.F;
			break;
		}
	}

	public int getEntryTime() {
		return entryTime;
	}

	public void setEntryTime(int entryTime) {
		this.entryTime = entryTime;
	}

	public Long getOriginNodeId() {
		return originNodeId;
	}

	public void setOriginNodeId(Long originNodeId) {
		this.originNodeId = originNodeId;
	}

	public Long getDestinationNodeId() {
		return destinationNodeId;
	}

	public void setDestinationNodeId(Long destinationNodeId) {
		this.destinationNodeId = destinationNodeId;
	}

	public Direction getDirection() {
		return direction;
	}

	public void setDirection(Direction direction) {
		this.direction = direction;
	}

	public double getSpeedMutiplier() {
		return speedMutiplier;
	}

	public void setSpeedMutiplier(double speedMutiplier) {
		this.speedMutiplier = speedMutiplier;
	}

	public double getTrainLength() {
		return trainLength;
	}

	public void setTrainLength(double trainLength) {
		this.trainLength = trainLength;
	}

	public int getToneladas() {
		return toneladas;
	}

	public void setToneladas(int toneladas) {
		this.toneladas = toneladas;
	}

	public boolean isHazmat() {
		return isHazmat;
	}

	public void setHazmat(boolean isHazmat) {
		this.isHazmat = isHazmat;
	}

	public int getSaStatus() {
		return saStatus;
	}

	public void setSaStatus(int saStatus) {
		this.saStatus = saStatus;
	}

	public Hashtable<Long, Double> getScheduleList() {
		return scheduleList;
	}

	public void setScheduleList(Hashtable<Long, Double> scheduleList) {
		this.scheduleList = scheduleList;
	}

	public int getTwt() {
		return twt;
	}

	public void setTwt(int twt) {
		this.twt = twt;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public double getSpeed(Track arc, Territory territory) {
		switch (arc.getType()) {
		case MAIN_ZERO:
			if (direction == Direction.EASTBOUND)
				return territory.getSpeedWestEast() * speedMutiplier;
			else
				return territory.getSpeedEastWest() * speedMutiplier;
		case MAIN_ONE:
			if (direction == Direction.EASTBOUND)
				return territory.getSpeedWestEast() * speedMutiplier;
			else
				return territory.getSpeedEastWest() * speedMutiplier;
		case MAIN_TWO:
			if (direction == Direction.EASTBOUND)
				return territory.getSpeedWestEast() * speedMutiplier;
			else
				return territory.getSpeedEastWest() * speedMutiplier;
		case CROSSOVER:
			return territory.getSpeedCrossovers();
		case SIDING:
			return territory.getSpeedSindings();
		case SWITCH:
			return territory.getSpeedCrossovers();
		default:
			return 0.0;
		}
	}

	public int getTravelTime(Track track, Territory territory) {
		double length = track.getLength();
		double speed = getSpeed(track, territory);
		double time = length / speed;
		return InstantesUtil.horaToInstante(time);
	}

	public int getSchedTime(Long idNode) {
		if (scheduleList.containsKey(idNode)) {
			double minSched = scheduleList.get(idNode);
			return InstantesUtil.minToInstante(minSched);
		} else
			return InstantesUtil.getInstanteMax();
	}
}
